package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.DocumentInfo;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.enums.DocumentInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.DocumentInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.DocumentInfoRequest;
import cn.stylefeng.guns.modular.business.service.DocumentExcerptsService;
import cn.stylefeng.guns.modular.business.service.DocumentInfoService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文献信息表业务实现层
 *
 * @author zhangyaowen
 * @date 2021/10/28 16:51
 */
@Service
public class DocumentInfoServiceImpl extends ServiceImpl<DocumentInfoMapper, DocumentInfo> implements DocumentInfoService {

    @Resource
    private SubUseBrowseService subUseBrowseService;
    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private DocumentExcerptsService documentExcerptsService;


    @Override
    public void add(DocumentInfoRequest documentInfoRequest) {
        DocumentInfo documentInfo = new DocumentInfo();
        BeanUtil.copyProperties(documentInfoRequest, documentInfo);
        this.save(documentInfo);
    }

    @Override
    public void del(DocumentInfoRequest documentInfoRequest) {
        DocumentInfo documentInfo = this.queryDocumentInfo(documentInfoRequest);
        this.removeById(documentInfo.getId());
    }

    @Override
    public void edit(DocumentInfoRequest documentInfoRequest) {
        DocumentInfo documentInfo = this.queryDocumentInfo(documentInfoRequest);
        BeanUtil.copyProperties(documentInfoRequest, documentInfo);
        this.updateById(documentInfo);
    }

    @Override
    public DocumentInfo detail(DocumentInfoRequest documentInfoRequest) {
        return this.queryDocumentInfo(documentInfoRequest);
    }

//    @Override
//    public PageResult<DocumentInfo> findPage(DocumentInfoRequest documentInfoRequest) {
//        LambdaQueryWrapper<DocumentInfo> wrapper = createWrapper(documentInfoRequest);
//        Page<DocumentInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
//        return PageResultFactory.createPageResult(sysRolePage);
//    }

    @Override
    public PageResult<Map<String, Object>> findPage(String year,String value) {
        String[] years = {};
        if(!year.equals("") ) {
            years = StrUtil.splitToArray(year, ";");
        }
        LambdaQueryWrapper<DocumentInfo> wrapper = createWrapperes(years,value);
        Page<DocumentInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);

        PageResult<DocumentInfo> projectSciencePageResult =  PageResultFactory.createPageResult(sysRolePage);
        List<DocumentInfo> list = projectSciencePageResult.getRows();
        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        List<Map<String,Object>> mapList = new ArrayList<>();
        for(DocumentInfo documentInfo : list){
            Map<String, Object> map = new HashMap<String, Object>();
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
            String jmid = YunHeKey.WXDJ+documentInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            map.put("title",documentInfo.getDocTitle());
//            map.put("docName",documentInfo.getDocName());
            map.put("docAuthor",documentInfo.getDocAuthor());
            map.put("docHistory",documentInfo.getDocHistory());
            map.put("annalsFrom",documentInfo.getDocAnnalsfrom());
            map.put("excerptsDoc",documentInfo.getExcerptsDoc());
            mapList.add(map);

        }
        pageResult.setRows(mapList);
        pageResult.setPageNo(projectSciencePageResult.getPageNo());
        pageResult.setTotalRows(projectSciencePageResult.getTotalRows());
        pageResult.setPageSize(projectSciencePageResult.getPageSize());
        pageResult.setTotalPage(projectSciencePageResult.getTotalPage());
        return pageResult;
    }


    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<DocumentInfo> createWrapperes( String[] years, String value) {
        LambdaQueryWrapper<DocumentInfo> queryWrapper = new LambdaQueryWrapper<DocumentInfo>();
        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(value), DocumentInfo::getDocName, value).or()
                .like(ObjectUtil.isNotNull(value), DocumentInfo::getDocAuthor, value).or()
                .like(ObjectUtil.isNotNull(value), DocumentInfo::getDocHistory, value).or()
                .like(ObjectUtil.isNotNull(value), DocumentInfo::getDocAnnalsfrom, value));
        if( years.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < years.length; i++) {
                    String ye = years[i];
                    wrapper.like(ObjectUtil.isNotEmpty(ye), DocumentInfo::getDocSecond, ye);
                    if (i != years.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        return queryWrapper;//.orderByDesc(DocumentInfo::getHistoryDating);
    }

    @Override
    public List<DocumentInfo> findList(DocumentInfoRequest documentInfoRequest) {
        LambdaQueryWrapper<DocumentInfo> wrapper = this.createWrapper(documentInfoRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/10/28 16:51
     */
    private DocumentInfo queryDocumentInfo(DocumentInfoRequest documentInfoRequest) {
        DocumentInfo documentInfo = this.getById(documentInfoRequest.getId());
        if (ObjectUtil.isEmpty(documentInfo)) {
            throw new ServiceException(DocumentInfoExceptionEnum.DOCUMENTINFO_NOT_EXISTED);
        }
        return documentInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/10/28 16:51
     */
    private LambdaQueryWrapper<DocumentInfo> createWrapper(DocumentInfoRequest documentInfoRequest) {
        LambdaQueryWrapper<DocumentInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = documentInfoRequest.getId();
        String docSecond = documentInfoRequest.getDocSecond();
        String docSecondcode = documentInfoRequest.getDocSecondcode();
        String docThird = documentInfoRequest.getDocThird();
        String docThirdcode = documentInfoRequest.getDocThirdcode();
        String excerptsDoc = documentInfoRequest.getExcerptsDoc();
        String docName = documentInfoRequest.getDocName();
        String docAuthor = documentInfoRequest.getDocAuthor();
        String docHistory = documentInfoRequest.getDocHistory();
        String docIntroduction = documentInfoRequest.getDocIntroduction();
        String docAnnalsfrom = documentInfoRequest.getDocAnnalsfrom();
        String docAnnalspage = documentInfoRequest.getDocAnnalspage();

        queryWrapper.eq(ObjectUtil.isNotNull(id), DocumentInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(docSecond), DocumentInfo::getDocSecond, docSecond);
        queryWrapper.like(ObjectUtil.isNotEmpty(docSecondcode), DocumentInfo::getDocSecondcode, docSecondcode);
        queryWrapper.like(ObjectUtil.isNotEmpty(docThird), DocumentInfo::getDocThird, docThird);
        queryWrapper.like(ObjectUtil.isNotEmpty(docThirdcode), DocumentInfo::getDocThirdcode, docThirdcode);
        queryWrapper.like(ObjectUtil.isNotEmpty(excerptsDoc), DocumentInfo::getExcerptsDoc, excerptsDoc);
        queryWrapper.like(ObjectUtil.isNotEmpty(docName), DocumentInfo::getDocName, docName);
        queryWrapper.like(ObjectUtil.isNotEmpty(docAuthor), DocumentInfo::getDocAuthor, docAuthor);
        queryWrapper.like(ObjectUtil.isNotEmpty(docHistory), DocumentInfo::getDocHistory, docHistory);
        queryWrapper.like(ObjectUtil.isNotEmpty(docIntroduction), DocumentInfo::getDocIntroduction, docIntroduction);
        queryWrapper.like(ObjectUtil.isNotEmpty(docAnnalsfrom), DocumentInfo::getDocAnnalsfrom, docAnnalsfrom);
        queryWrapper.like(ObjectUtil.isNotEmpty(docAnnalspage), DocumentInfo::getDocAnnalspage, docAnnalspage);

        return queryWrapper;
    }

    @Override
    public List<Map<String,Object>> findChoose() {
        LambdaQueryWrapper<DocumentInfo> queryWrapper = new LambdaQueryWrapper<>();
        List<Map<String,Object>> mapList = new ArrayList<>();
        List<Map<String,Object>> findList = new ArrayList<>();
        Map<String, Object> findRiver = new HashMap<String, Object>();
        List<DocumentInfo> list= this.list(queryWrapper);
        for(DocumentInfo documentInfo : list){

            Map<String, Object> map = new HashMap<String, Object>();
            Map<String, Object> map1 = new HashMap<String, Object>();
            if(!documentInfo.getDocSecond().equals("")){
                map.put("docYear",documentInfo.getDocSecond());
                map.put("docCode",documentInfo.getDocSecondcode());
                mapList.add(map);
            }
        }
        //List<map>去重 生成新的list
        ArrayList<Map<String, Object>> rive = mapList.stream()
                .collect(Collectors
                        .collectingAndThen(Collectors
                                .toCollection(() -> new TreeSet<>(new Comparator<Map<String, Object>>() {
                                    @Override    //重写比较器
                                    public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                                        if (o1.get("docYear").equals(o2.get("docYear"))) {
                                            return 0;
                                        }
                                        return 1;
                                    }

                                })), ArrayList::new));
        findRiver.put("list",rive);
        findRiver.put("title","时期");
        findList.add(findRiver);
        return findList;
    }

    @Override
    public Map<String, Object> toReview(String jmId) {
        byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(jmId, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YHSJ后面真实的的id
        String id = StrUtil.subAfter(decryptStr,YunHeKey.WXDJ,false);
        if ("".equals(id)) {
            Map<String, Object> mapLists = new HashMap<>();
            return mapLists;
        }
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid;
        if (ObjectUtil.isNotNull(request)) {
            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(DocumentInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<DocumentInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(ObjectUtil.isNotEmpty(id), DocumentInfo::getId, id);
        List<DocumentInfo> riverInfoList = this.list(queryWrapper);

        List<Map<String, Object>> mapList = new ArrayList<>();
        for (DocumentInfo documentInfo : riverInfoList) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(documentInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = DocumentInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {

                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名
                        if ("docTitle".equals(field.getName()) || "docIntroduction".equals(field.getName())) {
                            if ("docTitle".equals(field.getName())){
                                p.put("title", map.get(field.getName()));
                            }else {
                                p.put(field.getName(), map.get(field.getName()));
                            }
                        } else {
                            mp.put("key", aa.value());
                            mp.put("value", map.get(field.getName()));

                            if (i != 1) {
                                mplist.add(mp);
                            }
                        }
                    }
                    i++;
                }
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.YHWXDJ,mapList.get(0).get("title").toString(),userid,request);
        }
//        if(!YunHeUtil.saveBrowse(YunHeKey.YHWXDJ,mapList.get(0).get("docName").toString(),userid)){
//            maps.put("browseError","浏览记录录入失败");
//        }
//        Map<String, Object> objectMap = new HashMap<>();
//        Map<String, Object> objectMaps = new HashMap<>();
//        mapList1 = documentExcerptsService.findExcerpts(riverInfoList.get(0).getExcerptsDoc());
//        if(mapList1.size()>0) {
//            objectMap.put("list", mapList1);
//            objectMap.put("title", "相关节选文献");
//            objectMaps.put("allList",objectMap);
//        }
//        maps.putAll(mapList.get(0));
//        maps.putAll(objectMaps);
        return mapList.get(0);
    }

    @Override
    public List<Map<String,Object>> findAllList(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<DocumentInfo> wrapper = createWrapperByAll(riverList,townList,times,name);
        List<DocumentInfo> list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(DocumentInfo documentInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
//            Map<String, Object> map1 = new HashMap<String, Object>();
//            map = JSONObject.parseObject(JSONObject.toJSONString(eventsInfo), Map.class);
            map.put("title", documentInfo.getDocTitle());
            map.put("historyDating","");
            map.put("theCommon","");
            map.put("from",documentInfo.getDocAnnalsfrom() );
            map.put("createTime",DateUtil.format(documentInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.WXDJ);
            map.put("excerptsDoc",documentInfo.getExcerptsDoc());
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.WXDJ+documentInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            mapList.add(map);
        }
        return mapList;
    }
    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<DocumentInfo> createWrapperByAll(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<DocumentInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), DocumentInfo::getDocName, name).or()
                .like(ObjectUtil.isNotNull(name), DocumentInfo::getDocAnnalsfrom, name).or()
                .like(ObjectUtil.isNotNull(name), DocumentInfo::getDocHistory, name));

        if( times.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < times.length; i++) {
                    String time = times[i];
                    wrapper.like(ObjectUtil.isNotEmpty(time), DocumentInfo::getDocHistory, time);
                    if (i != times.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }

//        for(int i=0 ;i<times.length;i++) {
//            String time = times[i];
//            queryWrapper.like(ObjectUtil.isNotEmpty(time), EventsInfo::getEventsSecond, time);
//            if(i !=times.length-1) {
//                queryWrapper.or();
//            }
//        }
        return queryWrapper;
    }
}